package GUI;

import util.User;
import util.TravelRecordDAO;
import util.TravelRecord;

import javax.swing.*;
import java.awt.*;
import java.util.Map;
import java.util.Map.Entry;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import javax.swing.table.DefaultTableModel;

/**
 * 数据分析面板，用于分析用户的出行数据
 */
public class DataAnalysisPanel extends JPanel {
    private User currentUser;
    private JPanel barChartPanel; // 柱状图面板
    private JPanel pieChartPanel; // 饼状图面板
    private JPanel lineChartPanel; // 折线图面板
    private JPanel tablePanel; // 表格面板
    private Map<String, JLabel> metricsLabels = new HashMap<>();

    public DataAnalysisPanel(User user) {
        this.currentUser = user;

        // 设置布局
        setLayout(new BorderLayout(10, 10));
        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        // 创建标题
        JLabel titleLabel = new JLabel("出行数据分析", JLabel.CENTER);
        titleLabel.setFont(new Font("等线", Font.BOLD, 18));
        add(titleLabel, BorderLayout.NORTH);

        // 创建主面板
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));

        // 创建指标面板（移至顶部）
        JPanel metricsPanel = createMetricsPanel();
        mainPanel.add(metricsPanel, BorderLayout.NORTH);

        // 创建图表网格面板（2行2列）
        JPanel chartsGridPanel = new JPanel(new GridLayout(2, 2, 15, 15));

        // 创建并添加柱状图面板
        barChartPanel = new JPanel(new BorderLayout());
        barChartPanel.setBorder(BorderFactory.createTitledBorder("出行方式统计"));
        updateTravelTypeChart();
        chartsGridPanel.add(barChartPanel);

        // 创建并添加饼状图面板
        pieChartPanel = new JPanel(new BorderLayout());
        pieChartPanel.setBorder(BorderFactory.createTitledBorder("出行方式占比"));
        updateTravelTypePieChart();
        chartsGridPanel.add(pieChartPanel);

        // 创建并添加折线图面板
        lineChartPanel = new JPanel(new BorderLayout());
        lineChartPanel.setBorder(BorderFactory.createTitledBorder("每月出行趋势"));
        updateTravelTrendLineChart();
        chartsGridPanel.add(lineChartPanel);

        // 创建并添加表格面板
        tablePanel = new JPanel(new BorderLayout());
        tablePanel.setBorder(BorderFactory.createTitledBorder("出行详细数据"));
        updateTravelDataTable();
        chartsGridPanel.add(tablePanel);

        mainPanel.add(chartsGridPanel, BorderLayout.CENTER);
        add(mainPanel, BorderLayout.CENTER);

        // 创建操作面板
        JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JButton refreshButton = new JButton("刷新数据");
        refreshButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateTravelTypeChart();
                updateTravelTypePieChart();
                updateTravelTrendLineChart();
                updateTravelDataTable();
                updateMetrics();
            }
        });
        actionPanel.add(refreshButton);

        add(actionPanel, BorderLayout.SOUTH);
    }

    /**
     * 创建指标面板
     */
    private JPanel createMetricsPanel() {
        JPanel panel = new JPanel(new GridLayout(1, 3, 10, 10));
        panel.setBorder(BorderFactory.createTitledBorder("出行统计指标"));

        // 平均出行距离
        JPanel distancePanel = new JPanel(new BorderLayout(5, 5));
        distancePanel.setBorder(BorderFactory.createEtchedBorder());
        JLabel distanceTitleLabel = new JLabel("平均出行距离", JLabel.CENTER);
        distanceTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
        distancePanel.add(distanceTitleLabel, BorderLayout.NORTH);

        JLabel distanceValueLabel = new JLabel("0.00 公里", JLabel.CENTER);
        distanceValueLabel.setFont(new Font("等线", Font.BOLD, 24));
        distanceValueLabel.setForeground(new Color(65, 105, 225)); // 皇家蓝
        distancePanel.add(distanceValueLabel, BorderLayout.CENTER);

        panel.add(distancePanel);

        // 总出行次数
        JPanel countPanel = new JPanel(new BorderLayout(5, 5));
        countPanel.setBorder(BorderFactory.createEtchedBorder());
        JLabel countTitleLabel = new JLabel("总出行次数", JLabel.CENTER);
        countTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
        countPanel.add(countTitleLabel, BorderLayout.NORTH);

        JLabel countValueLabel = new JLabel("0 次", JLabel.CENTER);
        countValueLabel.setFont(new Font("等线", Font.BOLD, 24));
        countValueLabel.setForeground(new Color(0, 128, 0)); // 绿色
        countPanel.add(countValueLabel, BorderLayout.CENTER);

        panel.add(countPanel);

        // 平均每次积分
        JPanel pointsPanel = new JPanel(new BorderLayout(5, 5));
        pointsPanel.setBorder(BorderFactory.createEtchedBorder());
        JLabel pointsTitleLabel = new JLabel("平均每次积分", JLabel.CENTER);
        pointsTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
        pointsPanel.add(pointsTitleLabel, BorderLayout.NORTH);

        JLabel pointsValueLabel = new JLabel("0 分", JLabel.CENTER);
        pointsValueLabel.setFont(new Font("等线", Font.BOLD, 24));
        pointsValueLabel.setForeground(new Color(210, 105, 30)); // 巧克力色
        pointsPanel.add(pointsValueLabel, BorderLayout.CENTER);

        panel.add(pointsPanel);

        // 存储组件引用
        metricsLabels.put("distance", distanceValueLabel);
        metricsLabels.put("count", countValueLabel);
        metricsLabels.put("points", pointsValueLabel);

        // 更新指标数据
        updateMetrics();

        return panel;
    }

    /**
     * 更新出行方式柱状图
     */
    public void updateTravelTypeChart() {
        // 清空图表面板
        barChartPanel.removeAll();

        // 获取用户的出行统计数据
        TravelRecordDAO recordDAO = new TravelRecordDAO();
        Map<String, Integer> stats = recordDAO.getUserTravelStats(currentUser.getId());

        if (stats.isEmpty()) {
            JLabel emptyLabel = new JLabel("暂无出行数据", JLabel.CENTER);
            emptyLabel.setFont(new Font("等线", Font.PLAIN, 16));
            barChartPanel.add(emptyLabel, BorderLayout.CENTER);
        } else {
            // 创建简单的柱状图面板
            JPanel chartContent = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2d = (Graphics2D) g;
                    // 启用抗锯齿
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                    // 计算最大值，用于缩放
                    int maxCount = 0;
                    for (int count : stats.values()) {
                        if (count > maxCount) {
                            maxCount = count;
                        }
                    }

                    // 如果没有数据，直接返回
                    if (maxCount == 0) {
                        return;
                    }

                    // 绘制图表
                    int barWidth = 50;
                    int barSpacing = 20;
                    int startX = (getWidth() - (stats.size() * (barWidth + barSpacing) - barSpacing)) / 2;
                    int bottomY = getHeight() - 50;
                    int maxBarHeight = bottomY - 50;

                    int x = startX;

                    // 颜色数组，用于不同的柱子
                    Color[] colors = {
                            new Color(65, 105, 225), // 皇家蓝
                            new Color(210, 105, 30), // 巧克力色
                            new Color(0, 128, 0), // 绿色
                            new Color(139, 0, 139), // 洋红
                            new Color(218, 165, 32) // 金菊黄
                    };

                    int colorIndex = 0;

                    // 绘制每个柱子
                    for (Entry<String, Integer> entry : stats.entrySet()) {
                        String type = entry.getKey();
                        int count = entry.getValue();

                        // 计算柱子高度
                        int barHeight = (int) ((double) count / maxCount * maxBarHeight);

                        // 设置柱子颜色
                        g2d.setColor(colors[colorIndex % colors.length]);
                        colorIndex++;

                        // 绘制柱子
                        g2d.fillRect(x, bottomY - barHeight, barWidth, barHeight);

                        // 绘制柱子边框
                        g2d.setColor(Color.BLACK);
                        g2d.drawRect(x, bottomY - barHeight, barWidth, barHeight);

                        // 绘制数值
                        String countText = String.valueOf(count);
                        FontMetrics fm = g2d.getFontMetrics();
                        int textWidth = fm.stringWidth(countText);
                        g2d.drawString(countText, x + (barWidth - textWidth) / 2, bottomY - barHeight - 5);

                        // 绘制类别标签
                        textWidth = fm.stringWidth(type);
                        g2d.drawString(type, x + (barWidth - textWidth) / 2, bottomY + 20);

                        // 移动到下一个柱子位置
                        x += barWidth + barSpacing;
                    }

                    // 绘制Y轴
                    g2d.setColor(Color.BLACK);
                    g2d.drawLine(startX - 10, 50, startX - 10, bottomY);
                    g2d.drawLine(startX - 10, bottomY, x, bottomY);

                    // 绘制Y轴刻度
                    int stepCount = 5;
                    FontMetrics fm = g2d.getFontMetrics();
                    for (int i = 0; i <= stepCount; i++) {
                        int y = bottomY - (i * maxBarHeight / stepCount);
                        g2d.drawLine(startX - 15, y, startX - 10, y);

                        int value = i * maxCount / stepCount;
                        String valueText = String.valueOf(value);
                        int textWidth = fm.stringWidth(valueText);
                        g2d.drawString(valueText, startX - 20 - textWidth, y + 5);
                    }
                }
            };

            chartContent.setPreferredSize(new Dimension(500, 300));
            barChartPanel.add(chartContent, BorderLayout.CENTER);

            // 添加图表标题和说明
            JLabel chartTitleLabel = new JLabel("不同出行方式使用次数统计", JLabel.CENTER);
            chartTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
            barChartPanel.add(chartTitleLabel, BorderLayout.NORTH);

            JLabel chartDescLabel = new JLabel("横轴：出行方式，纵轴：次数", JLabel.CENTER);
            barChartPanel.add(chartDescLabel, BorderLayout.SOUTH);
        }

        // 重新绘制面板
        barChartPanel.revalidate();
        barChartPanel.repaint();
    }

    /**
     * 更新出行方式饼图
     */
    public void updateTravelTypePieChart() {
        // 清空图表面板
        pieChartPanel.removeAll();

        // 获取用户的出行统计数据
        TravelRecordDAO recordDAO = new TravelRecordDAO();
        Map<String, Integer> stats = recordDAO.getUserTravelStats(currentUser.getId());

        if (stats.isEmpty()) {
            JLabel emptyLabel = new JLabel("暂无出行数据", JLabel.CENTER);
            emptyLabel.setFont(new Font("等线", Font.PLAIN, 16));
            pieChartPanel.add(emptyLabel, BorderLayout.CENTER);
        } else {
            // 创建简单的饼图面板
            JPanel chartContent = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2d = (Graphics2D) g;
                    // 启用抗锯齿
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                    // 计算总数
                    int total = 0;
                    for (int count : stats.values()) {
                        total += count;
                    }

                    // 如果没有数据，直接返回
                    if (total == 0) {
                        return;
                    }

                    // 饼图尺寸和位置
                    int pieSize = Math.min(getWidth(), getHeight()) - 80;
                    int centerX = getWidth() / 2;
                    int centerY = getHeight() / 2;

                    // 颜色数组
                    Color[] colors = {
                            new Color(65, 105, 225), // 皇家蓝
                            new Color(210, 105, 30), // 巧克力色
                            new Color(0, 128, 0), // 绿色
                            new Color(139, 0, 139), // 洋红
                            new Color(218, 165, 32) // 金菊黄
                    };

                    // 绘制饼图
                    int startAngle = 0;
                    int colorIndex = 0;

                    // 图例Y坐标起点
                    int legendY = 50;

                    for (Entry<String, Integer> entry : stats.entrySet()) {
                        String type = entry.getKey();
                        int count = entry.getValue();

                        // 计算扇形的角度
                        int arcAngle = (int) Math.round(360.0 * count / total);

                        // 设置扇形颜色
                        Color color = colors[colorIndex % colors.length];
                        g2d.setColor(color);
                        colorIndex++;

                        // 绘制扇形
                        g2d.fillArc(centerX - pieSize / 2, centerY - pieSize / 2,
                                pieSize, pieSize, startAngle, arcAngle);

                        // 绘制扇形边框
                        g2d.setColor(Color.BLACK);
                        g2d.drawArc(centerX - pieSize / 2, centerY - pieSize / 2,
                                pieSize, pieSize, startAngle, arcAngle);

                        // 计算百分比
                        double percentage = 100.0 * count / total;

                        // 计算扇形中心点的角度（弧度）
                        double midAngleRad = Math.toRadians(startAngle + arcAngle / 2.0);

                        // 计算标签位置（在扇形外部）
                        int labelRadius = pieSize / 2 + 20;
                        int labelX = centerX + (int) (Math.cos(midAngleRad) * labelRadius);
                        int labelY = centerY - (int) (Math.sin(midAngleRad) * labelRadius);

                        // 绘制标签
                        String label = String.format("%s: %d (%.1f%%)", type, count, percentage);
                        FontMetrics fm = g2d.getFontMetrics();
                        int textWidth = fm.stringWidth(label);
                        g2d.drawString(label, labelX - textWidth / 2, labelY);

                        // 绘制图例
                        g2d.setColor(color);
                        g2d.fillRect(getWidth() - 150, legendY, 15, 15);
                        g2d.setColor(Color.BLACK);
                        g2d.drawRect(getWidth() - 150, legendY, 15, 15);
                        g2d.drawString(type, getWidth() - 130, legendY + 12);

                        // 更新角度和图例位置
                        startAngle += arcAngle;
                        legendY += 25;
                    }
                }
            };

            chartContent.setPreferredSize(new Dimension(500, 300));
            pieChartPanel.add(chartContent, BorderLayout.CENTER);

            // 添加图表标题和说明
            JLabel chartTitleLabel = new JLabel("出行方式占比分析", JLabel.CENTER);
            chartTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
            pieChartPanel.add(chartTitleLabel, BorderLayout.NORTH);

            JLabel chartDescLabel = new JLabel("各类出行方式使用比例", JLabel.CENTER);
            pieChartPanel.add(chartDescLabel, BorderLayout.SOUTH);
        }

        // 重新绘制面板
        pieChartPanel.revalidate();
        pieChartPanel.repaint();
    }

    /**
     * 更新出行趋势折线图
     */
    public void updateTravelTrendLineChart() {
        // 清空图表面板
        lineChartPanel.removeAll();

        // 模拟月度数据（实际项目中应从数据库获取）
        Map<String, Integer> monthlyData = new HashMap<>();
        monthlyData.put("1月", 5);
        monthlyData.put("2月", 8);
        monthlyData.put("3月", 12);
        monthlyData.put("4月", 10);
        monthlyData.put("5月", 15);
        monthlyData.put("6月", 20);

        if (monthlyData.isEmpty()) {
            JLabel emptyLabel = new JLabel("暂无趋势数据", JLabel.CENTER);
            emptyLabel.setFont(new Font("等线", Font.PLAIN, 16));
            lineChartPanel.add(emptyLabel, BorderLayout.CENTER);
        } else {
            // 创建简单的折线图面板
            JPanel chartContent = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2d = (Graphics2D) g;
                    // 启用抗锯齿
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                    // 计算最大值，用于缩放
                    int maxCount = 0;
                    for (int count : monthlyData.values()) {
                        if (count > maxCount) {
                            maxCount = count;
                        }
                    }

                    // 如果没有数据，直接返回
                    if (maxCount == 0) {
                        return;
                    }

                    // 设置图表边距
                    int leftMargin = 60;
                    int rightMargin = 30;
                    int topMargin = 30;
                    int bottomMargin = 60;

                    // 计算图表区域
                    int chartWidth = getWidth() - leftMargin - rightMargin;
                    int chartHeight = getHeight() - topMargin - bottomMargin;

                    // 坐标轴起点和终点
                    int xAxisStartX = leftMargin;
                    int xAxisStartY = getHeight() - bottomMargin;
                    int xAxisEndX = getWidth() - rightMargin;
                    int yAxisStartX = leftMargin;
                    int yAxisStartY = getHeight() - bottomMargin;
                    int yAxisEndY = topMargin;

                    // 绘制坐标轴
                    g2d.setColor(Color.BLACK);
                    // X轴
                    g2d.drawLine(xAxisStartX, xAxisStartY, xAxisEndX, xAxisStartY);
                    // Y轴
                    g2d.drawLine(yAxisStartX, yAxisStartY, yAxisStartX, yAxisEndY);

                    // 点的X坐标间隔
                    int pointSpacing = chartWidth / (monthlyData.size() + 1);

                    // 将月份数据转换为有序的列表
                    List<String> months = new ArrayList<>(monthlyData.keySet());
                    // 这里可以添加月份排序逻辑

                    // 存储点的坐标
                    int[] xPoints = new int[months.size()];
                    int[] yPoints = new int[months.size()];

                    // 绘制数据点和标签
                    for (int i = 0; i < months.size(); i++) {
                        String month = months.get(i);
                        int count = monthlyData.get(month);

                        // 计算点的坐标
                        int x = leftMargin + (i + 1) * pointSpacing;
                        int y = topMargin + chartHeight - (int) (chartHeight * ((double) count / maxCount));

                        // 存储点的坐标
                        xPoints[i] = x;
                        yPoints[i] = y;

                        // 绘制数据点
                        g2d.setColor(new Color(65, 105, 225));
                        g2d.fillOval(x - 4, y - 4, 8, 8);
                        g2d.setColor(Color.BLACK);
                        g2d.drawOval(x - 4, y - 4, 8, 8);

                        // 绘制数值
                        String countText = String.valueOf(count);
                        FontMetrics fm = g2d.getFontMetrics();
                        int textWidth = fm.stringWidth(countText);
                        g2d.drawString(countText, x - textWidth / 2, y - 10);

                        // 绘制X轴标签
                        g2d.drawString(month, x - fm.stringWidth(month) / 2, xAxisStartY + 20);

                        // 绘制刻度线
                        g2d.drawLine(x, xAxisStartY, x, xAxisStartY + 5);
                    }

                    // 绘制折线
                    g2d.setColor(new Color(65, 105, 225));
                    g2d.setStroke(new BasicStroke(2));
                    for (int i = 0; i < xPoints.length - 1; i++) {
                        g2d.drawLine(xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1]);
                    }

                    // 绘制Y轴刻度
                    g2d.setColor(Color.BLACK);
                    g2d.setStroke(new BasicStroke(1));
                    int ySteps = 5;
                    FontMetrics fm = g2d.getFontMetrics();
                    for (int i = 0; i <= ySteps; i++) {
                        int y = yAxisStartY - (i * chartHeight / ySteps);
                        g2d.drawLine(yAxisStartX - 5, y, yAxisStartX, y);

                        int value = i * maxCount / ySteps;
                        String valueText = String.valueOf(value);
                        g2d.drawString(valueText, yAxisStartX - 10 - fm.stringWidth(valueText), y + 5);
                    }
                }
            };

            chartContent.setPreferredSize(new Dimension(500, 300));
            lineChartPanel.add(chartContent, BorderLayout.CENTER);

            // 添加图表标题和说明
            JLabel chartTitleLabel = new JLabel("月度出行趋势分析", JLabel.CENTER);
            chartTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
            lineChartPanel.add(chartTitleLabel, BorderLayout.NORTH);

            JLabel chartDescLabel = new JLabel("横轴：月份，纵轴：出行次数", JLabel.CENTER);
            lineChartPanel.add(chartDescLabel, BorderLayout.SOUTH);
        }

        // 重新绘制面板
        lineChartPanel.revalidate();
        lineChartPanel.repaint();
    }

    /**
     * 更新出行数据表格
     */
    public void updateTravelDataTable() {
        // 清空表格面板
        tablePanel.removeAll();

        // 获取出行记录数据
        TravelRecordDAO recordDAO = new TravelRecordDAO();
        List<TravelRecord> records = recordDAO.getUserTravelRecords(currentUser.getId());

        if (records.isEmpty()) {
            JLabel emptyLabel = new JLabel("暂无出行记录", JLabel.CENTER);
            emptyLabel.setFont(new Font("等线", Font.PLAIN, 16));
            tablePanel.add(emptyLabel, BorderLayout.CENTER);
        } else {
            // 创建表格模型
            String[] columnNames = { "日期", "出行方式", "距离(公里)", "起点", "终点" };
            DefaultTableModel model = new DefaultTableModel(columnNames, 0);

            // 添加数据行
            for (TravelRecord record : records) {
                Object[] row = {
                        record.getTravelDate(),
                        record.getTravelType(),
                        record.getDistance(),
                        record.getStartLocation(),
                        record.getEndLocation()
                };
                model.addRow(row);
            }

            // 创建表格
            JTable table = new JTable(model);
            table.setFillsViewportHeight(true);
            table.setRowHeight(25);
            table.getTableHeader().setReorderingAllowed(false);

            // 创建滚动面板并添加表格
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane.setPreferredSize(new Dimension(500, 300));
            tablePanel.add(scrollPane, BorderLayout.CENTER);

            // 添加表格标题
            JLabel tableTitleLabel = new JLabel("出行记录详细数据", JLabel.CENTER);
            tableTitleLabel.setFont(new Font("等线", Font.BOLD, 14));
            tablePanel.add(tableTitleLabel, BorderLayout.NORTH);
        }

        // 重新绘制面板
        tablePanel.revalidate();
        tablePanel.repaint();
    }

    /**
     * 更新指标数据
     */
    public void updateMetrics() {
        TravelRecordDAO recordDAO = new TravelRecordDAO();

        // 获取用户的出行统计数据
        Map<String, Integer> stats = recordDAO.getUserTravelStats(currentUser.getId());

        // 计算总出行次数
        int totalCount = 0;
        for (int count : stats.values()) {
            totalCount += count;
        }

        // 更新出行次数显示
        metricsLabels.get("count").setText(totalCount + " 次");

        // 获取平均出行距离
        double avgDistance = recordDAO.getUserAverageDistance(currentUser.getId());

        // 更新平均出行距离显示
        metricsLabels.get("distance").setText(String.format("%.2f 公里", avgDistance));

        // 计算平均每次积分
        double avgPoints = totalCount > 0 ? (double) currentUser.getPoints() / totalCount : 0;

        // 更新平均每次积分显示
        metricsLabels.get("points").setText(String.format("%.1f 分", avgPoints));
    }
}
